package com.gitee.wsl.common.ui.ext

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import com.gitee.wsl.unit.angle.AngleUnit
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/**
 * Check if the size is not empty.
 *
 */
fun Size.isNotEmpty(): Boolean = !isEmpty()

val Size.TopLeftOffset: Offset
    get() = Offset.Zero

val Size.TopCenterOffset: Offset
    get() = Offset(width / 2, 0f)

val Size.TopRightOffset: Offset
    get() = Offset(width, 0f)

val Size.CenterLeftOffset: Offset
    get() = Offset(0f, height / 2)

val Size.CenterOffset: Offset
    get() = Offset(width / 2, height / 2)

val Size.CenterRightOffset: Offset
    get() = Offset(width, height / 2)

val Size.BottomLeftOffset: Offset
    get() = Offset(0f, height)

val Size.BottomCenterOffset: Offset
    get() = Offset(width / 2, height)

val Size.BottomRightOffset: Offset
    get() = Offset(width, height)


/**
 * Calculate the size of the rotated
 *
 */
fun Size.calculateRotatedSize(angle: AngleUnit): Size {
    val radians = angle.radian
    val affineTransform: (Pair<Double, Double>) -> Pair<Double, Double> = { corner ->
        val x = corner.first * kotlin.math.cos(radians) - corner.second * kotlin.math.sin(radians)
        val y = corner.first * kotlin.math.sin(radians) + corner.second * kotlin.math.cos(radians)
        Pair(x, y)
    }

    var minX = Double.MAX_VALUE
    var minY = Double.MAX_VALUE
    var maxX = Double.MIN_VALUE
    var maxY = Double.MIN_VALUE
    val corners = arrayOf(
        Pair(0.0, 0.0),
        Pair(width.toDouble(), 0.0),
        Pair(0.0, height.toDouble()),
        Pair(width.toDouble(), height.toDouble())
    )
    for (corner in corners) {
        val result = affineTransform(corner)
        minX = min(minX, result.first)
        minY = min(minY, result.second)
        maxX = max(maxX, result.first)
        maxY = max(maxY, result.second)
    }

    val newWidth = abs(maxX - minX).toFloat()
    val newHeight = abs(maxY - minY).toFloat()
    return Size(width = newWidth, height = newHeight)
}


/**
 * Ensures that this value is not less than the specified minimumValue.
 *
 */
fun Size.coerceAtLeast(minimumValue: Size): Size = Size(
    width = width.coerceAtLeast(minimumValue.width),
    height = height.coerceAtLeast(minimumValue.height),
)

/**
 * Ensures that this value is not greater than the specified maximumValue.
 *
 */
fun Size.coerceAtMost(maximumValue: Size): Size = Size(
    width = width.coerceAtMost(maximumValue.width),
    height = height.coerceAtMost(maximumValue.height),
)